use codegraph_core::{GraphSystem, Parser};
use codegraph_parser::TreeSitterParser;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize logging
    tracing_subscriber::fmt::init();

    println!("🚀 CodeGraph-RT Basic Usage Example");
    println!("=====================================");

    // 1. Create a graph system
    println!("\n1. Creating graph system...");
    let system = GraphSystem::new().await?;
    println!("✅ Graph system created successfully");

    // 2. Create parsers for different languages
    println!("\n2. Creating language parsers...");
    
    let python_parser = TreeSitterParser::python()?;
    println!("✅ Python parser created");
    
    let js_parser = TreeSitterParser::javascript()?;
    println!("✅ JavaScript parser created");
    
    let rust_parser = TreeSitterParser::rust()?;
    println!("✅ Rust parser created");

    // 3. Parse some sample code
    println!("\n3. Parsing sample code...");
    
    let python_code = r#"
def fibonacci(n):
    """Calculate the nth Fibonacci number."""
    if n <= 1:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

class Calculator:
    def __init__(self):
        self.history = []
    
    def add(self, a, b):
        result = a + b
        self.history.append(f"{a} + {b} = {result}")
        return result

# Usage
calc = Calculator()
result = calc.add(fibonacci(5), fibonacci(6))
print(f"Result: {result}")
"#;

    let tree = python_parser.parse(python_code, None).await?;
    println!("✅ Python code parsed successfully");
    println!("   Language: {}", tree.language());
    println!("   Source length: {} characters", tree.source().len());
    
    let root = tree.root_node();
    println!("   Root node type: {}", root.kind());
    println!("   Child count: {}", root.child_count());

    // 4. Parse JavaScript code
    let js_code = r#"
function factorial(n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

class MathUtils {
    constructor() {
        this.pi = 3.14159;
    }
    
    circleArea(radius) {
        return this.pi * radius * radius;
    }
    
    static isPrime(num) {
        if (num < 2) return false;
        for (let i = 2; i <= Math.sqrt(num); i++) {
            if (num % i === 0) return false;
        }
        return true;
    }
}

const utils = new MathUtils();
console.log(`Area of circle with radius 5: ${utils.circleArea(5)}`);
console.log(`Is 17 prime? ${MathUtils.isPrime(17)}`);
"#;

    let js_tree = js_parser.parse(js_code, None).await?;
    println!("✅ JavaScript code parsed successfully");
    println!("   Language: {}", js_tree.language());
    println!("   Source length: {} characters", js_tree.source().len());

    // 5. Parse Rust code
    let rust_code = r#"
use std::collections::HashMap;

#[derive(Debug, Clone)]
pub struct Person {
    name: String,
    age: u32,
}

impl Person {
    pub fn new(name: String, age: u32) -> Self {
        Self { name, age }
    }
    
    pub fn greet(&self) -> String {
        format!("Hello, my name is {} and I'm {} years old", self.name, self.age)
    }
}

fn main() {
    let mut people = HashMap::new();
    
    let alice = Person::new("Alice".to_string(), 30);
    let bob = Person::new("Bob".to_string(), 25);
    
    people.insert("alice", alice);
    people.insert("bob", bob);
    
    for (key, person) in &people {
        println!("{}: {}", key, person.greet());
    }
}
"#;

    let rust_tree = rust_parser.parse(rust_code, None).await?;
    println!("✅ Rust code parsed successfully");
    println!("   Language: {}", rust_tree.language());
    println!("   Source length: {} characters", rust_tree.source().len());

    // 6. Demonstrate incremental parsing
    println!("\n4. Demonstrating incremental parsing...");
    
    let modified_python_code = r#"
def fibonacci(n):
    """Calculate the nth Fibonacci number using memoization."""
    memo = {}
    
    def fib_helper(n):
        if n in memo:
            return memo[n]
        if n <= 1:
            return n
        memo[n] = fib_helper(n - 1) + fib_helper(n - 2)
        return memo[n]
    
    return fib_helper(n)

class Calculator:
    def __init__(self):
        self.history = []
    
    def add(self, a, b):
        result = a + b
        self.history.append(f"{a} + {b} = {result}")
        return result
    
    def multiply(self, a, b):
        result = a * b
        self.history.append(f"{a} * {b} = {result}")
        return result

# Usage
calc = Calculator()
result = calc.multiply(fibonacci(5), fibonacci(6))
print(f"Result: {result}")
"#;

    let incremental_tree = python_parser.parse(modified_python_code, Some(tree.as_ref())).await?;
    println!("✅ Incremental parsing completed");
    println!("   New source length: {} characters", incremental_tree.source().len());

    // 7. Summary
    println!("\n🎉 Example completed successfully!");
    println!("=====================================");
    println!("This example demonstrated:");
    println!("• Creating a graph system");
    println!("• Parsing multiple programming languages");
    println!("• Basic incremental parsing");
    println!("• Tree-sitter integration");
    
    println!("\nNext steps for full implementation:");
    println!("• Complete node and edge extraction");
    println!("• Implement graph storage");
    println!("• Add query capabilities");
    println!("• Build REST API");
    println!("• Add real-time change watching");

    Ok(())
}
